<template>
	<view class="su-form-comp" :style="{ width: compWidth }">
		<!-- 标题 -->
		<view v-if="showComp('title')" class="left" :style="'width:' + titleWidth">
			<text class="title-view" :style="titleStyle">{{ title }}</text>
			<text class="su-redhot" v-if="isMust">*</text>
		</view>
		<!-- 内容 -->
		<view :class="['center', textRight ? 'text-right' : '']">
			<input
				v-if="showComp('input')"
				:class="['input-view', disabled ? 'disabled' : '']"
				:type="type"
				:placeholder="placeholder"
				:value="bindValue"
				@input="_dataChange($event, type)"
				@blur="_inputBlur($event, type)"
				:disabled="disabled"
				:placeholder-style="'color:' + placeholderColor"
				:maxlength="maxlength"
			/>
			<textarea
				v-if="showComp('textarea')"
				:class="['textarea-view', disabled ? 'disabled' : '']"
				:placeholder-style="'color:' + placeholderColor"
				:style="'min-height:' + areaHeight + ';padding-left:' + iosPadding + ';width:100%'"
				:placeholder="placeholder"
				:value="bindValue"
				:auto-height="true"
				@input="_dataChange($event, type)"
				@blur="_inputBlur($event, type)"
				:disabled="disabled"
				:maxlength="maxlength"
			></textarea>
			<view v-if="showComp('textarea') && maxlength > 0" class="text-limit">
				<text>{{ lencount + '/' + maxlength }}</text>
			</view>
			<text v-if="showComp('label')" :class="['label-view', disabled ? 'disabled' : '']" :style="bindValue ? 'color:' + placeholderColor : ''">
				{{ bindValue || placeholder || '' }}
			</text>
			<!-- 日期时间选择器 -->
			<view v-if="showComp('date')" @click="_dateClick" class="center-min-height">
				<text :class="['label-view', disabled ? 'disabled' : '']" :style="handlePlcolor(dateValue) ? 'color:' + placeholderColor : ''">{{ dateValue || placeholder }}</text>
			</view>
			<!-- 区域选择器 -->
			<view v-if="showComp('region')" @click="_regionClick" class="center-min-height">
				<text :class="['label-view', disabled ? 'disabled' : '']" :style="handlePlcolor(regionValue) ? 'color:' + placeholderColor : ''">
					{{ regionValue || placeholder }}
				</text>
			</view>
			<!-- 单选选择器 -->
			<view v-if="showComp('picker')" @click="_pickerClick" class="center-min-height">
				<text :class="['label-view', disabled ? 'disabled' : '']" :style="handlePlcolor(select['name']) ? 'color:' + placeholderColor : ''">
					{{ select['name'] || placeholder }}
				</text>
			</view>
			<!-- 多项选择器 -->
			<view v-if="showComp('multiple')" @click="_multipleClick" class="center-min-height">
				<text :class="['label-view', disabled ? 'disabled' : '']" :style="handlePlcolor(select['name']) ? 'color:' + placeholderColor : ''">
					{{ select['name'] || placeholder }}
				</text>
			</view>
			<!-- 多项选择器 -->
			<view v-if="showComp('mlabel')" @click="_mlabelClick" class="center-min-height">
				<text :class="['label-view', disabled ? 'disabled' : '']" :style="handlePlcolor(select['name']) ? 'color:' + placeholderColor : ''">
					{{ select['name'] || placeholder }}
				</text>
			</view>
			<view v-if="showComp('input') && clearBtn && bindValue !== ''" class="su-form-iconclear" @click="$emit('update:bindValue', '')">
				<text class="iconfont icon-clear"></text>
			</view>
			<slot name="center"></slot>
		</view>
		<view :class="['right', disabled ? 'disabled' : '']">
			<!-- 只有类型为select才会显示箭头 -->
			<text v-if="(type == 'select' || type == 'multiple' || type == 'region' || type == 'mlabel') && showRightIcon === true" class="iconfont select-icon">&#xe669;</text>
			<text v-if="showComp('date') && !showDisicon" class="iconfont date-icon">&#xe610;</text>
			<text v-if="showDisicon" class="iconfont disabled-icon">&#xe6c1;</text>
			<slot name="right"></slot>
		</view>
		<!-- 单选 picker -->
		<hd-picker
			ref="selectpicker"
			v-if="type == 'select'"
			mode="selector"
			:selectList="pickerData"
			:defaultVal="handleSelect(select)"
			:themeColor="getMainColor()"
			@confirm="_dataChange($event, 'select')"
			@cancel="_cancelEvent"
		></hd-picker>
		<!-- 省市区选择 picker -->
		<hd-picker
			ref="regionpicker"
			v-if="showComp('region')"
			mode="region"
			@confirm="_dataChange($event, 'region')"
			@cancel="_cancelEvent"
		></hd-picker>
		<!-- 日期时间 picker -->
		<hd-picker
			ref="datepicker"
			v-if="showComp('date')"
			:mode="handleMode"
			:defaultVal="dateArray"
			@confirm="_dataChange($event, type)"
			:current="dateArray.length == 0"
			endYear="2099"
			@cancel="_cancelEvent"
		></hd-picker>
		<!-- 多选 picker -->
		<hd-multiple
			v-if="showComp('multiple')"
			ref="multiple"
			@confirm="_dataChange($event, type)"
			@cancel="_cancelEvent"
			:listData="selectData"
			:selectValue="bindValue"
			:field="field"
			:cancelText="popCancelText"
		/>
		<!-- 单选 picker -->
		<hd-picker
			ref="mlabel"
			v-if="showComp('mlabel')"
			mode="mlabel"
			:selectList="pickerData"
			:defaultVal="handleSelect(select)"
			@confirm="_dataChange($event, 'select')"
			@cancel="_cancelEvent"
		></hd-picker>
	</view>
</template>

<script>
import hdMultiple from '../hd-multiple/hd-multiple.vue';
import hdPicker from '../hd-picker/hd-picker.vue';
// 时间工具
import dateUtils from '../libs/date.js'
export default {
	name: 'hdform',
	components: {
		hdMultiple,
		hdPicker
	},
	model: {
		prop: 'bindValue',
		event: 'updateModel'
	},
	provide() {
		return {
			pform: this
		};
	},
	inject: {
		pdata: {
			from: 'pdata',
			default: null
		}
	},
	props: {
		// 标题
		title: {
			type: String,
			default: ''
		},
		// 标题颜色
		titleStyle: {
			type: [String, Object],
			default() {
				return '';
			}
		},
		// 标题宽度
		titleWidth: {
			type: String,
			default: '180rpx'
		},
		textRight: {
			type: Boolean,
			default: false
		},
		// 类型
		type: {
			type: String,
			default: 'text'
		},
		// 占位提示
		placeholder: {
			type: String,
			default: ''
		},
		// 占位提示颜色
		placeholderColor: {
			type: String,
			default() {
				return '#636463';
			}
		},
		// 如果类型为select时生效
		selectData: {
			type: Array,
			default() {
				return [];
			}
		},
		// 如果类型为select时需要传区分字段
		field: {
			type: String,
			default: ''
		},
		// 绑定字段
		bindValue: {
			type: [String, Number],
			default: ''
		},
		// p-data嵌套时绑定的字段
		bindRef: {
			type: [String],
			default: ''
		},
		// p-data的rowid参数
		bindRowid: {
			type: [String],
			default: ''
		},
		// 是否禁用
		disabled: {
			type: Boolean,
			default: false
		},
		// 是否显示红点
		isMust: {
			type: Boolean,
			default: false
		},
		compWidth: {
			type: String,
			default() {
				// return this.isMiniProgram() ? '630rpx' : '680rpx';
				return '680rpx';
			}
		},
		// 是否显示禁止编辑按钮
		showDisicon: {
			type: Boolean,
			default: false
		},
		// 是否显示右侧图标
		showRightIcon: {
			type: Boolean,
			default: true
		},
		areaHeight: {
			type: String,
			default: '200rpx'
		},
		// 是否默认选择select值
		defaultSelect: {
			type: Boolean,
			default: false
		},
		// 使用原生日期选择对话框
		useOgDate: {
			type: Boolean,
			default: false
		},
		// 显示清除按钮
		clearBtn: {
			type: Boolean,
			default: false
		},
		// 区域默认数据
		regionData: {
			type: Object,
			default() {
				return {};
			}
		},
		// popCancelText
		popCancelText: {
			type: String,
			default() {
				return '取消';
			}
		},
		maxlength: {
			type: Number,
			default: -1
		}
	},
	watch: {
		selectData() {
			this._handleSelect();
		},
		bindValue() {
			this._handleDefault();
		}
	},
	created() {
		this._handleSelect();
		this._handleDefault();
		if (this.platform === 'ios') {
			this.iosPadding = '6rpx';
		}
	},
	computed: {
		isMiniProgram() {
			// 判断是否是小程序环境
			return this.platform === 'mp-weixin';
		},
		isMobile() {
			// 判断是否是移动端平台
			return ['android', 'ios'].includes(this.platform);
		},
		isAndroid() {
			return this.platform === 'android';
		},
		isIOS() {
			return this.platform === 'ios';
		},
		// 根据类型判断显示隐藏
		showComp(_type) {
			return function (_type) {
				switch (_type) {
					case 'title':
						if (this.title) return true;
						else return false;
						break;
					case 'input':
						if (this.type == 'text' || this.type == 'number' || this.type == 'idcard' || this.type == 'digit') return true;
						else return false;
						break;
					case 'textarea':
						if (this.type == 'textarea') return true;
						else return false;
						break;
					case 'label':
						if (this.type == 'label') return true;
						else return false;
						break;
					case 'date':
						if (this.type == 'datetime' || this.type == 'date') return true;
						else return false;
						break;
					case 'picker':
						if (this.type == 'select') return true;
						else return false;
						break;
					case 'region':
						if (this.type == 'region') return true;
						else return false;
						break;
					case 'multiple':
						if (this.type == 'multiple') return true;
						else return false;
						break;
					case 'mlabel':
						if (this.type == 'mlabel') return true;
						else return false;
						break;
					default:
						return false;
						break;
				}
			};
		},
		// 处理
		handleSelect(value) {
			return function () {
				if (this.type == 'select') {
					return [this.select['name']];
				}
			};
		},
		// 处理date picker类型
		handleMode() {
			if (this.type == 'date') {
				return 'date';
			} else if (this.type == 'datetime') {
				return 'dateTime';
			}
		},
		// 计算pl颜色
		handlePlcolor(value) {
			return function (value) {
				if (this.disabled == false) {
					if (value) return false;
					else return true;
				} else {
					return false;
				}
			};
		}
	},
	data() {
		return {
			pickerMode: 'datetime',
			dateArray: [],
			pickerData: [],
			dateValue: '',
			regionValue: '',
			select: { index: 0, name: '', code: '', id: '' },
			iosPadding: '0rpx',
			lencount: 0, // 用来计数触发填写内容长度
			platform: '' // 平台信息
		};
	},
	mounted() {
		this.getSystemInfo(); // 在组件挂载后获取系统信息
	},
	methods: {
		// 获取系统信息
		getSystemInfo() {
			uni.getSystemInfo({
				success: (res) => {
					this.platform = res.platform.toLowerCase(); // 获取平台信息并转换为小写
				}
			});
		},
		_handleDefault() {
			// 处理时间
			if (this.type == 'datetime' || this.type == 'date') {
				if (this.bindValue && typeof this.bindValue == 'number') {
					this._handleDate(this.bindValue);
				} else if (this.bindValue && typeof this.bindValue == 'string') {
					let time = new Date(this.bindValue.replace(/-/g, '/')).getTime();
					if (isNaN(time)) {
						this.dateValue = '';
						this.dateArray = [];
					} else {
						this._handleDate(time);
					}
				} else {
					this.dateValue = '';
					this.dateArray = [];
				}
			}
			// 处理选择
			if (this.type == 'select') {
				if (typeof this.bindValue != 'undefined' && this.bindValue != '' && this.bindValue != null) {
					if (this.selectData.length > 0) this._selectCode(this.selectData);
				}
			}
			// 处理选择
			if (this.type == 'mlabel') {
			}
			// 处理多选
			if (this.type == 'multiple') {
				if (typeof this.bindValue != 'undefined' && this.bindValue != '' && this.bindValue != null) {
					if (this.selectData.length > 0) {
						if (this.bindValue && typeof this.bindValue == 'string') {
							let selectList = this.bindValue.split(',');
							let list = [],
								nameList = [];
							let field = this.field ? this.field : 'code';
							for (let item of this.selectData) {
								if (selectList.includes(item[field])) {
									list.push(item[field]);
									nameList.push(item['name']);
								}
							}
							this.select[field] = list.join(',');
							this.select['name'] = nameList.join(',');
						} else {
							this.select['name'] = this.bindValue;
						}
					} else {
						this.select['name'] = this.bindValue;
					}
				} else {
					this.select['name'] = this.bindValue;
				}
			}
			// 处理地址
			if (this.type === 'region') {
				let regionData = this.regionData;
				let lastValue = '';
				if (regionData.hasOwnProperty('province') || regionData.hasOwnProperty('city') || regionData.hasOwnProperty('region')) {
					if (regionData['province']) {
						lastValue += regionData['province'] + ' ';
					}
					if (regionData['city']) {
						lastValue += regionData['city'] + ' ';
					}
					if (regionData['region']) {
						lastValue += regionData['region'];
					}
					this.regionValue = lastValue;
				}
			}
			// 处理长文本
			if (this.type === 'textarea') {
				if (this.bindValue || this.bindValue === 0) {
					this.lencount = this.bindValue.length;
				}
			}
		},
		_handleDate(value) {
			var formatStr = 'yyyy-MM-dd hh:mm';
			if (this.type == 'date') formatStr = 'yyyy-MM-dd';
			this.dateValue = dateUtils.formatDate(value, formatStr);
			this.dateArray = dateUtils.getDateArray(value, this.type, false);
		},
		_selectCode(rows) {
			if (typeof rows[0][this.field ? this.field : 'code'] != 'undefined') {
				for (var j in rows) {
					if (this.bindValue == rows[j][this.field ? this.field : 'code']) {
						this.select['index'] = j;
						this.select['name'] = rows[j]['name'];
						this.select['code'] = rows[j]['code'];
						if (this.field && this.field != 'code' && this.field != 'name') {
							this.select[this.field] = rows[j][this.field];
						}
					}
				}
			} else {
				this.select['name'] = this.bindValue;
			}
		},
		_handleSelect() {
			var rows = this.selectData;
			this.pickerData = [];
			for (var i in rows) {
				if (i == 0) {
					this.select['index'] = 0;
					if (typeof this.bindValue != 'undefined' && this.bindValue != '' && this.bindValue != null) {
						this._selectCode(rows);
					} else {
						if (this.defaultSelect) {
							this.select = { ...rows[i] };
							this.$emit('updateModel', this.select[this.field]);
							this.$emit('update:bindValue', this.select[this.field]);
							this.$emit('change', {
								type: this.type,
								field: this.field,
								data: this.select
							});
						}
					}
				}
				this.pickerData.push({
					label: rows[i]['name'],
					value: rows[i]['code']
				});
			}
			if (rows.length === 0) {
				this.pickerData.push({
					label: '',
					value: ''
				});
			}
		},
		_pickerClick() {
			!this.disabled && this.$refs.selectpicker.show();
		},
		_multipleClick() {
			!this.disabled && this.$refs.multiple.open(this.bindValue);
		},
		_mlabelClick() {
			!this.disabled && this.$refs.mlabel.show();
		},
		// 省市区选择
		_regionClick() {
			!this.disabled && this.$refs.regionpicker.show();
		},
		// 日期时间选择
		_dateClick() {
			if (this.isMobile) {
				let self = this;
				if (!this.disabled && this.useOgDate) {
					let ndate = new Date(this.bindValue);
					var tstyle = {};
					tstyle.date = ndate;
					plus.nativeUI.pickDate(
						(edate) => {
							let re = { result: '' };
							let ed = edate.date;
							let year = ed.getFullYear(),
								month = ed.getMonth() + 1,
								date = ed.getDate();
							let sdate = year + '-' + month + '-' + date;
							if (this.type == 'datetime') {
								showTimeDialog(sdate);
							} else {
								re.result = sdate;
								this._dataChange(re, 'date');
							}
						},
						null,
						tstyle
					);
					function showTimeDialog(sde) {
						var styles = {};
						styles.title = '请选择时间：';
						styles.time = ndate;
						plus.nativeUI.pickTime(
							(e) => {
								let re = { result: '' };
								let td = e.date;
								let hos = td.getHours(),
									mis = td.getMinutes(),
									ses = td.getSeconds();
								re.result = sde + ' ' + hos + ':' + mis + ':' + ses;
								self._dataChange(re, 'datetime');
							},
							null,
							styles
						);
					}
				} else if (!this.disabled) {
					this.$refs.datepicker.show();
				}
			} else {
				!this.disabled && this.$refs.datepicker.show();
			}
		},
		_inputBlur(e, type) {
			this.$emit('blur', { event: e, type });
		},
		_dataChange(e, type) {
			let tempValue = null,
				changeValue = null;
			if (type == 'select') {
				// 单选最终逻辑
				var index = e.defaultVal[0];
				this.select = { index: index, ...this.selectData[index] };
				tempValue = this.select[this.field];
				changeValue = {
					type: this.type,
					field: this.field,
					data: this.select
				};
			} else if (type == 'multiple') {
				// 多选选择
				let { result, value, name } = e;
				this.select['name'] = name;
				tempValue = value;
				changeValue = {
					type: this.type,
					field: this.field,
					data: { result, name, code: value }
				};
			} else if (type == 'text' || type == 'textarea' || type == 'number' || type == 'idcard' || type == 'digit') {
				let tvalue = e.detail.value;
				this.lencount = tvalue ? tvalue.length : 0;
				// 输入类型
				tempValue = e.detail.value;
				changeValue = e.detail.value;
			} else if (type == 'date' || type == 'datetime') {
				// 日期时间类型
				var dateResult = e.result,
					lResult = 0;
				if (this.isMobile || this.isMiniProgram) {
					dateResult = dateResult.replace(/-/g, '/');
				}
				lResult = new Date(dateResult).getTime();
				if (!this.bindValue) this._handleDate(lResult);
				tempValue = lResult;
				changeValue = dateResult;
			} else if (type == 'region') {
				this.regionValue = e.checkArr.join(' ');
				// 省市区
				tempValue = e.result;
				changeValue = e;
			} else {
				console.error('type类型不匹配');
			}
			// 小程序的数据改变兼容
			if (this.pdata && this.bindRef && this.bindRowid) {
				this.pdata.setValue(this.bindRef, tempValue, this.bindRowid);
			}
			this.$emit('update:bindValue', tempValue);
			this.$emit('updateModel', tempValue);
			this.$emit('change', changeValue);
		},
		// 弹框取消事件
		_cancelEvent() {
			this.$emit('cancel');
		}
	}
};
</script>

<style lang="scss">
.su-form-comp {
	position: relative;
	display: flex;
	flex-direction: row;
	align-items: center;
	line-height: 30upx;
	font-size: 30upx !important;
	flex: 1;
	width: 100%;
	.left {
		width: auto;
	}
	.center {
		position: relative;
		flex: 1;
		&.text-right {
			text-align: right !important;
			padding-right: 20upx !important;
		}
	}
	.right {
		width: auto;
		display: flex;
		align-items: center;
		.select-icon,
		.date-icon {
			font-size: 36upx;
			line-height: 36upx;
			color:#101010;
		}

		.disabled-icon {
			color: #a1a1a1;
		}
	}
	.su-redhot {
		position: absolute;
		left: -20rpx;
		color: red;
		font-size: 30upx;
		margin-top: 5upx;
		padding-left: 5upx;
	}
	.su-form-iconclear {
		align-items: center;
		line-height: 0upx;
		padding: 10upx 0upx;
		position: absolute;
		right: 0upx;
		top: -4upx;
	}

	input,
	textarea {
		color: #101010;
	}

	.title-view {
		font-size: 30upx;
		color: #343434;
	}

	.label-view {
		font-size: 30upx;
		color: #343434;
		&.pl {
			color: #636463;
		}
	}

	.center-min-height {
		min-height: 35upx;
	}

	// 禁用颜色
	.label-view.disabled,
	.input-view.disabled,
	.textarea-view.disabled,
	.right.disabled .select-icon,
	.right.disabled .date-icon,
	.right.disabled .disabled-icon {
		color: #636463;
	}

	.input-view {
		height: 54upx;
		font-size: 30upx !important;
		line-height: 48upx;
	}

	.textarea-view {
		font-size: 30upx !important;
		line-height: 48upx;
	}

	.text-limit {
		color: #888888;
		font-size: 26upx;
		line-height: 26upx;
		text-align: right;
	}
}
</style>
